home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / lib / posix / exec.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  3KB  |  132 lines

  1. #include <lib.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4.  
  5. extern char **environ;        /* environment pointer */
  6.  
  7. #define    PTRSIZE    (sizeof(char *))
  8.  
  9. PUBLIC int execl(name, arg0)
  10. char *name;
  11. char *arg0;
  12. {
  13.   return(execve(name, &arg0, environ));
  14. }
  15.  
  16. PUBLIC int execle(name, argv)
  17. char *name, *argv;
  18. {
  19.   char **p;
  20.   p = (char **) &argv;
  21.   while (*p++)            /* null statement */
  22.     ;
  23.   return(execve(name, &argv, (char **) *p));
  24. }
  25.  
  26. PUBLIC int execv(name, argv)
  27. char *name, *argv[];
  28. {
  29.   return(execve(name, argv, environ));
  30. }
  31.  
  32.  
  33. PUBLIC int execve(path, argv, envp)
  34. char *path;            /* pointer to name of file to be executed */
  35. char *argv[];            /* pointer to argument array */
  36. char *envp[];            /* pointer to environment */
  37. {
  38.   register char **argtop;
  39.   register char **envtop;
  40.  
  41.   /* Count the argument pointers and environment pointers. */
  42.   for (argtop = argv; *argtop != (char *) NULL; ) argtop++;
  43.   for (envtop = envp; *envtop != (char *) NULL; ) envtop++;
  44.   return(__execve(path, argv, envp, argtop - argv, envtop - envp));
  45. }
  46.  
  47.  
  48. PUBLIC int __execve(path, argv, envp, nargs, nenvps)
  49. char *path;            /* pointer to name of file to be executed */
  50. char *argv[];            /* pointer to argument array */
  51. char *envp[];            /* pointer to environment */
  52. int nargs;            /* number of args */
  53. int nenvps;            /* number of environment strings */
  54. {
  55. /* This is split off from execve to be called from execvp, so execvp does not
  56.  * have to allocate up to ARG_MAX bytes just to prepend "sh" to the arg array.
  57.  */
  58.  
  59.   char *hp, **ap, *p;
  60.   int i, stackbytes, npointers, overflow, temp;
  61.   char *stack;
  62.  
  63.   /* Decide how big a stack is needed. Be paranoid about overflow. */
  64. #if ARG_MAX > INT_MAX
  65. #error /* overflow checks and sbrk depend on sizes being ints */
  66. #endif
  67.   overflow = FALSE;
  68.   npointers = 1 + nargs + 1 + nenvps + 1;    /* 1's for argc and NULLs */
  69.   stackbytes = nargs + nenvps;        /* for nulls in strings */
  70.   if (nargs < 0 || nenvps < 0 || stackbytes < nargs || npointers < stackbytes)
  71.     overflow = TRUE;
  72.   for (i = PTRSIZE; i != 0; i--) {
  73.     temp = stackbytes + npointers;
  74.     if (temp < stackbytes) overflow = TRUE;
  75.     stackbytes = temp;
  76.   }
  77.   for (i = 0, ap = argv; i < nargs; i++) {
  78.     temp = stackbytes + strlen(*ap++);
  79.     if (temp < stackbytes) overflow = TRUE;
  80.     stackbytes = temp;
  81.   }
  82.   for (i = 0, ap = envp; i < nenvps; i++) {
  83.     temp = stackbytes + strlen(*ap++);
  84.     if (temp < stackbytes) overflow = TRUE;
  85.     stackbytes = temp;
  86.   }
  87.   temp = stackbytes + PTRSIZE - 1;
  88.   if (temp < stackbytes) overflow = TRUE;
  89.   stackbytes = (temp / PTRSIZE) * PTRSIZE;
  90.  
  91.   /* Check for overflow before committing sbrk. */
  92.   if (overflow || stackbytes > ARG_MAX) {
  93.     errno = E2BIG;
  94.     return(-1);
  95.   }
  96.  
  97.   /* Allocate the stack. */
  98.   stack = sbrk(stackbytes);
  99.   if (stack == (char *) -1) {
  100.     errno = E2BIG;
  101.     return(-1);
  102.   }
  103.  
  104.   /* Prepare the stack vector and argc. */
  105.   ap = (char **) stack;
  106.   hp = &stack[npointers * PTRSIZE];
  107.   *ap++ = (char *) nargs;
  108.  
  109.   /* Prepare the argument pointers and strings. */
  110.   for (i = 0; i < nargs; i++) {
  111.     *ap++ = (char *) (hp - stack);
  112.     p = *argv++;
  113.     while ((*hp++ = *p++) != 0)
  114.         ;
  115.   }
  116.   *ap++ = (char *) NULL;
  117.  
  118.   /* Prepare the environment pointers and strings. */
  119.   for (i = 0; i < nenvps; i++) {
  120.     *ap++ = (char *) (hp - stack);
  121.     p = *envp++;
  122.     while ((*hp++ = *p++) != 0)
  123.         ;
  124.   }
  125.   *ap++ = (char *) NULL;
  126.  
  127.   /* Do the real work. */
  128.   temp = callm1(MM, EXEC, len(path), stackbytes, 0, path, stack, NIL_PTR);
  129.   sbrk(-stackbytes);
  130.   return(temp);
  131. }
  132.